home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 03 - 1987 / 03.07 Jul 87 / LMC source stuff / LMC Source < prev   
Encoding:
Text File  |  1987-04-26  |  10.2 KB  |  410 lines  |  [TEXT/PJMM]

  1. {        Lazy Man's Color by Steve Sheets 4/20/87        }
  2.  
  3. {    Simple Demonstration of Mac // Color using the ForeColor & BackColor.    }
  4. {    This program Load and displays a MacPaint document in any 2 colors.        }
  5.  
  6. PROGRAM LMC;
  7.  
  8. {    Various Constants:    Menu ID Numbers, Window Size, Window Placement,     }
  9. {        BitMap Size and Number of Colors.    }
  10.     CONST
  11.         AppleMenuID = 300;
  12.         FileMenuID = 301;
  13.         EditMenuID = 302;
  14.         ForeMenuID = 303;
  15.         BackMenuID = 304;
  16.  
  17.         OffV = 40;
  18.         OffH = 40;
  19.         AboutH = 300;
  20.         AboutV = 140;
  21.         SizeH = 576;
  22.         SizeV1 = 360;
  23.         SizeV2 = 720;
  24.         BitW = 72;
  25.         NumSec = 2;
  26.  
  27.         XColor = 8;
  28.  
  29. {    Various Variables:    Menus, Bitmaps, Window, Colors, Done Flag & Title Name    }
  30.     VAR
  31.         Done : boolean;
  32.         AppleMenu, FileMenu, EditMenu, ForeMenu, BackMenu : MenuHandle;
  33.  
  34.         CWindow : windowptr;
  35.         CMap : ARRAY[1..NumSec] OF bitmap;
  36.         CData : ARRAY[1..NumSec] OF handle;
  37.  
  38.         ForeC, BackC : integer;
  39.         Title : str255;
  40.  
  41. {    Given Color Number (from 1 to XColor, as if selected by Menu),        }
  42. {        returns actual longint Color Number (for ForeColor or BackColor).    }
  43.     FUNCTION GetColor (N : integer) : longint;
  44.     BEGIN
  45.         CASE N OF
  46.             1 : 
  47.                 GetColor := BlackColor;
  48.             2 : 
  49.                 GetColor := WhiteColor;
  50.             3 : 
  51.                 GetColor := RedColor;
  52.             4 : 
  53.                 GetColor := GreenColor;
  54.             5 : 
  55.                 GetColor := BlueColor;
  56.             6 : 
  57.                 GetColor := CyanColor;
  58.             7 : 
  59.                 GetColor := MagentaColor;
  60.             8 : 
  61.                 GetColor := YellowColor;
  62.             OTHERWISE
  63.                 GetColor := WhiteColor;
  64.         END;
  65.     END;
  66.  
  67. {    Sets new ForeColor & BackColor and forces an Update so Window is    }
  68. {        redrawn in the new colors.    }
  69.     PROCEDURE DoColor (F, B : integer);
  70.         VAR
  71.             count : integer;
  72.             tempPort : Grafptr;
  73.     BEGIN
  74.         GetPort(tempPort);
  75.         SetPort(CWindow);
  76.  
  77.         IF F <> ForeC THEN
  78.             BEGIN
  79.                 FOR count := 1 TO XColor DO
  80.                     CheckItem(ForeMenu, count, count = F);
  81.                 ForeC := F;
  82.                 ForeColor(GetColor(ForeC));
  83.             END;
  84.  
  85.         IF B <> BackC THEN
  86.             BEGIN
  87.                 FOR count := 1 TO XColor DO
  88.                     CheckItem(BackMenu, count, count = B);
  89.                 BackC := B;
  90.                 BackColor(GetColor(BackC));
  91.             END;
  92.  
  93.         InvalRect(CWindow^.portRect);
  94.  
  95.         SetPort(tempPort);
  96.     END;
  97.  
  98. {    Loads MacPaint Picture in Bitmaps and displays it.    }
  99.     PROCEDURE DoLoad;
  100.         TYPE
  101.             diskBlock = PACKED ARRAY[1..512] OF QDbyte;
  102.         VAR
  103.             MyReply : SFReply;
  104.             MyType : SFtypelist;
  105.             tempPoint : point;
  106.             count : longint;
  107.             refNum, scanline, N : integer;
  108.             error : OSErr;
  109.             srcBuf : ARRAY[1..2] OF diskBlock;
  110.             srcPtr, dstPtr : Ptr;
  111.     BEGIN
  112.         tempPoint.v := 60;
  113.         tempPoint.h := 60;
  114.         MyType[0] := 'PNTG';
  115.         SFGetFile(tempPoint, '', NIL, 1, MyType, NIL, MyReply);
  116.         IF MyReply.good THEN
  117.             BEGIN
  118.                 Hlock(CData[1]);
  119.                 Hlock(CData[2]);
  120.  
  121.                 IF FSOpen(MyReply.fname, MyReply.vrefnum, refNum) = noErr THEN
  122.                     BEGIN
  123.  
  124.                         count := 512;
  125.                         error := FSRead(refNum, count, @srcBuf);
  126.  
  127.                         count := 1024;
  128.                         error := FSRead(refNum, count, @srcBuf);
  129.                         srcPtr := @srcBuf;
  130.  
  131.                         FOR N := 1 TO NumSec DO
  132.                             BEGIN
  133.                                 dstPtr := CData[N]^;
  134.                                 FOR scanline := 1 TO SizeV1 DO
  135.                                     BEGIN
  136.                                         UnpackBits(srcPtr, dstPtr, BitW);
  137.                                         IF ord(srcPtr) > (ord(@srcBuf) + 512) THEN
  138.                                             BEGIN
  139.                                                 srcBuf[1] := srcBuf[2];
  140.                                                 count := 512;
  141.                                                 error := FSRead(refNum, count, @srcBuf[2]);
  142.                                                 srcPtr := pointer(ord(srcPtr) - 512);
  143.                                             END;
  144.                                     END;
  145.                             END;
  146.  
  147.                         error := FSClose(refNum);
  148.                     END;
  149.                 HUnlock(CData[1]);
  150.                 HUnlock(CData[2]);
  151.             END;
  152.  
  153.         DoColor(ForeC, BackC);
  154.     END;
  155.  
  156. {    Creates a Rectangle centered on Screen (if window size is smaller then    }
  157. {    the screen) or starting at a standard offset (if window size is larger then    }
  158. {    then screen).    }
  159.     PROCEDURE CenterRect (VAR R : rect;
  160.                                     H, V : integer);
  161.         VAR
  162.             tempH : integer;
  163.     BEGIN
  164.         IF H > Screenbits.bounds.right THEN
  165.             tempH := OffH
  166.         ELSE
  167.             tempH := ((Screenbits.bounds.right - H) DIV 2);
  168.         SetRect(R, tempH, OffV, H + tempH, V + OffV);
  169.     END;
  170.  
  171. {    Draws text, centered in a rectangle in the About Box window in a    }
  172. {    certain color with a certain justification    }
  173.     PROCEDURE DoLine (S : str255;
  174.                                     H, Top, Bottom, J : integer;
  175.                                     C : longint);
  176.         VAR
  177.             tempInteger : integer;
  178.             tempRect : rect;
  179.     BEGIN
  180.         ForeColor(C);
  181.         tempInteger := ((AboutH - H) DIV 2);
  182.         SetRect(tempRect, tempInteger, Top, tempInteger + H, Bottom);
  183.         TextBox(POINTER(ord(@S) + 1), LENGTH(S), tempRect, J);
  184.     END;
  185.  
  186. {    Displays About Box (in color) until someone presses the button down.    }
  187.     PROCEDURE DoAbout;
  188.         VAR
  189.             tempWindow : windowptr;
  190.             tempRect : rect;
  191.             tempStr : str255;
  192.     BEGIN
  193.         CenterRect(tempRect, AboutH, AboutV);
  194.         tempWindow := NewWindow(NIL, tempRect, '', true, dBoxProc, POINTER(-1), false, 0);
  195.         SetPort(tempWindow);
  196.         TextFont(0);
  197.  
  198.         DoLine(CONCAT(Title, ' by Steve Sheets'), AboutH, 20, 39, teJustCenter, BlueColor);
  199.         DoLine('Sample Mac // Color Program', AboutH, 40, 59, teJustCenter, GreenColor);
  200.         DoLine('This program uses the ForeColor and BackColor Quickdraw commands to display a MacPaint document in two colors.', AboutH - 50, 60, AboutV, teJustLeft, RedColor);
  201.  
  202.         WHILE NOT button DO
  203.             ;
  204.  
  205.         DisposeWindow(tempWindow);
  206.     END;
  207.  
  208. {    Standard main menu procedure that handles menu selections.  Can show    }
  209. {    About Box, open Desk Accessories, Load in MacPaint file, change the Done        }
  210. {    Flag (so the program quits), handle edit commands (Cut,Copy,Paste,Clear),    }
  211. {    and change Foreground or Background color of the picture.}
  212.     PROCEDURE MainMenu (tempResult : LONGINT);
  213.         VAR
  214.             tempInteger : integer;
  215.             tempBoolean : boolean;
  216.             tempStr : STR255;
  217.     BEGIN
  218.         tempInteger := LoWord(tempResult);
  219.         CASE HiWord(tempResult) OF
  220.             AppleMenuID : 
  221.                 IF tempInteger = 1 THEN
  222.                     DoAbout
  223.                 ELSE
  224.                     BEGIN
  225.                         GetItem(appleMenu, tempInteger, tempStr);
  226.                         tempInteger := OpenDeskAcc(tempStr);
  227.                     END;
  228.             FileMenuID : 
  229.                 CASE tempInteger OF
  230.                     1 : 
  231.                         DoLoad;
  232.                     3 : 
  233.                         Done := true;
  234.                     OTHERWISE
  235.                 END;
  236.             EditMenuID : 
  237.                 tempBoolean := SystemEdit(tempInteger - 1);
  238.             ForeMenuID : 
  239.                 IF (tempInteger > 0) AND (tempInteger <= XColor) THEN
  240.                     DoColor(tempInteger, BackC);
  241.             BackMenuID : 
  242.                 IF (tempInteger > 0) AND (tempInteger <= XColor) THEN
  243.                     DoColor(ForeC, tempInteger);
  244.             OTHERWISE
  245.         END;
  246.         HiliteMenu(0);
  247.     END;
  248.  
  249. {    Setup for Menus, Window, Bitmaps,  Colors settings, Title and Done flag.    }
  250.     PROCEDURE DoSetup;
  251.         TYPE
  252.             DD = PACKED ARRAY[1..32000] OF 0..255;
  253.             PP = ^DD;
  254.             HH = ^PP;
  255.         VAR
  256.             tempStr : STR255;
  257.             tempRect : rect;
  258.             count : integer;
  259.             tempLong : longint;
  260.             tempH : HH;
  261.     BEGIN
  262.         Title := 'Lazy Man@s Color';
  263.         Title[9] := CHR(39);
  264.  
  265.         tempStr := ' ';
  266.         tempStr[1] := CHR(appleMark);
  267.         AppleMenu := NewMenu(AppleMenuID, tempStr);
  268.         AppendMenu(AppleMenu, CONCAT('About ', Title, '...;(-'));
  269.         AddResMenu(AppleMenu, 'DRVR');
  270.  
  271.         FileMenu := NewMenu(FileMenuID, 'File');
  272.         AppendMenu(FileMenu, 'Load MacPaint Documents/L;(-;Quit/Q');
  273.  
  274.         EditMenu := NewMenu(EditMenuID, 'Edit');
  275.         AppendMenu(EditMenu, 'Undo/Z;(-;Cut/X;Copy/C;Paste/V;Clear');
  276.  
  277.         ForeMenu := NewMenu(ForeMenuID, 'Set Foreground');
  278.         AppendMenu(ForeMenu, 'Black;White;Red;Green;Blue;Cyan;Magenta;Yellow');
  279.  
  280.         BackMenu := NewMenu(BackMenuID, 'Set Background');
  281.         AppendMenu(BackMenu, 'Black;White;Red;Green;Blue;Cyan;Magenta;Yellow');
  282.  
  283.         InsertMenu(AppleMenu, 0);
  284.         InsertMenu(FileMenu, 0);
  285.         InsertMenu(EditMenu, 0);
  286.         InsertMenu(ForeMenu, 0);
  287.         InsertMenu(BackMenu, 0);
  288.  
  289.         DrawMenuBar;
  290.  
  291.         CenterRect(tempRect, SizeH, SizeV2);
  292.         CWindow := NewWindow(NIL, tempRect, Title, true, 4, POINTER(-1), false, 0);
  293.  
  294.         CMap[1].rowBytes := BitW;
  295.         SetRect(CMap[1].bounds, 0, 0, SizeH, SizeV1);
  296.         CData[1] := NewHandle(BitW * SizeV1);
  297.         IF CData[1] <> NIL THEN
  298.             BEGIN
  299.                 tempH := HH(CData[1]);
  300.                 FOR count := 1 TO BitW * SizeV1 DO
  301.                     tempH^^[count] := 0;
  302.             END;
  303.         CMap[2].rowBytes := BitW;
  304.         SetRect(CMap[2].bounds, 0, SizeV1, SizeH, SizeV2);
  305.         CData[2] := NewHandle(BitW * SizeV1);
  306.         IF CData[2] <> NIL THEN
  307.             BEGIN
  308.                 tempH := HH(CData[2]);
  309.                 FOR count := 1 TO BitW * SizeV1 DO
  310.                     tempH^^[count] := 0;
  311.             END;
  312.  
  313.         IF (CData[1] = NIL) OR (CData[2] = NIL) THEN
  314.             BEGIN
  315.                 SetWTitle(CWindow, 'Not Enough Memmory');
  316.                 DisableItem(FileMenu, 1);
  317.             END;
  318.  
  319.         ForeC := 0;
  320.         BackC := 0;
  321.         DoColor(1, 2);
  322.  
  323.         InitCursor;
  324.  
  325.         Done := false;
  326.     END;
  327.  
  328. {    Standard main program loop that handles all events (ie. mouse down, key    }
  329. {    downs & updates) until the Done flag is set.    }
  330.     PROCEDURE MainLoop;
  331.         VAR
  332.             tempEvent : EventRecord;
  333.             tempWindow : windowptr;
  334.             tempCode : integer;
  335.             tempPort : Grafptr;
  336.             tempRect : rect;
  337.     BEGIN
  338.         REPEAT
  339.             SystemTask;
  340.             IF GetNextEvent(everyEvent, tempEvent) THEN
  341.                 BEGIN
  342.                     CASE tempEvent.what OF
  343.                         mouseDown : 
  344.                             BEGIN
  345.                                 tempCode := FindWindow(tempEvent.where, tempWindow);
  346.                                 CASE tempCode OF
  347.                                     inDrag, inContent : 
  348.                                         BEGIN
  349.                                             IF tempWindow <> FrontWindow THEN
  350.                                                 SelectWindow(tempWindow)
  351.                                             ELSE
  352.                                                 BEGIN
  353.                                                     IF Cwindow = tempWindow THEN
  354.                                                         BEGIN
  355.                                                             IF CWindow <> FrontWindow THEN
  356.                                                                 SelectWindow(CWIndow)
  357.                                                             ELSE
  358.                                                                 BEGIN
  359.                                                                     SetRect(tempRect, -25000, -25000, 25000, 25000);
  360.                                                                     DragWindow(CWindow, tempEvent.where, tempRect);
  361.                                                                 END;
  362.                                                         END;
  363.                                                 END;
  364.                                         END;
  365.                                     inMenuBar : 
  366.                                         MainMenu(MenuSelect(tempEvent.where));
  367.                                     inSysWindow : 
  368.                                         SystemClick(tempEvent, tempWindow);
  369.                                     OTHERWISE
  370.                                 END; { of tempCode case }
  371.                             END; { of mouseDown }
  372.                         keydown, autoKey : 
  373.                             IF BitAnd(tempEvent.modifiers, cmdKey) <> 0 THEN
  374.                                 MainMenu(MenuKey(CHR(tempEvent.message MOD 256)));
  375.                         updateEvt : 
  376.                             IF CWindow = WindowPtr(tempEvent.message) THEN
  377.                                 BEGIN
  378.                                     GetPort(tempPort);
  379.                                     SetPort(CWindow);
  380.                                     BeginUpdate(CWindow);
  381.  
  382.                                     IF CData[1] <> NIL THEN
  383.                                         BEGIN
  384.                                             Hlock(CData[1]);
  385.                                             CMap[1].baseAddr := CData[1]^;
  386.                                             CopyBits(CMap[1], CWindow^.portBits, CMap[1].bounds, CMap[1].bounds, srcCopy, NIL);
  387.                                             HUnlock(CData[1]);
  388.                                         END;
  389.                                     IF CData[2] <> NIL THEN
  390.                                         BEGIN
  391.                                             Hlock(CData[2]);
  392.                                             CMap[2].baseAddr := CData[2]^;
  393.                                             CopyBits(CMap[2], CWindow^.portBits, CMap[2].bounds, CMap[2].bounds, srcCopy, NIL);
  394.                                             HUnlock(CData[2]);
  395.                                         END;
  396.  
  397.                                     EndUpdate(CWindow);
  398.                                     SetPort(tempPort);
  399.                                 END;
  400.                         OTHERWISE
  401.                     END;
  402.                 END;
  403.         UNTIL Done;
  404.     END;
  405.  
  406. {    ***PROGRAM***    }
  407. BEGIN
  408.     DoSetup;
  409.     MainLoop;
  410. END.